package top.superflow.flow.runtime.context

import top.superflow.exception.RequestUnsupportedException
import top.superflow.flow.config.Identifiable
import top.superflow.lang.{CollectionUtils, StringUtils}

import scala.collection.mutable.Map


trait ContextHierachy extends Identifiable{

  private var parent : ContextHierachy = _

  private val children : Map[String, ContextHierachy] = Map()

  private var contextType : String = _

  def getParent = parent

  def setParent (p : ContextHierachy) = this.parent = p

  def getChildren = this.children

  def getContextType : String = {
    this.contextType
  }

  def setContextType(t : String) : Unit = {
    this.contextType = t
  }

  protected def isDirectParent(context : ContextHierachy): Boolean = {
    if(context == null || context.getContextType == null){
      return false
    }

    StringUtils.equals(this.getValidChildContextType, context.getContextType)
  }

  def setChildren(c: Map[String, ContextHierachy]) : Unit = {
    if(CollectionUtils.isEmpty(c)){
      children.clear()
      return;
    }

    this.children ++= c
  }

  def getValidChildContextType : String

  def addChild(c: ContextHierachy) : Unit = {
    if(c == null){
      return;
    }

    if(!this.isDirectParent(c)){
      throw new RequestUnsupportedException("The context type is " + c.getContextType + ", yet the child context type should only be " + this.getValidChildContextType)
    }

    this.children += (c.getKey -> c)
  }
}

object ContextHierachy{
  final val CONTEXT_TYPE_GLOBAL = "global"

  final val CONTEXT_TYPE_GROUP = "group"

  final val CONTEXT_TYPE_FLOW = "flow"

  final val CONTEXT_TYPE_NODE = "node"
}
